/////////////////////////////////////////////////////////////////////////////
// Name:        application.cpp
// Purpose:     
// Author:      Brant Young
// Modified by: 
// Created:     Mon May 14 21:43:02 2007
// RCS-ID:      
// Copyright:   Copyright (c) daodict.com 2007
// Licence:     GPL 2.0
/////////////////////////////////////////////////////////////////////////////
#include <wx/wx.h>
#include <wx/ffile.h>
#include <wx/log.h>
#include <wx/splash.h>
#include <wx/filesys.h>
#include <wx/fs_arc.h>
#include <wx/fs_mem.h>
#include <wx/snglinst.h>

#include "application.h"
#include "splashframe.h"
#include "mainframe.h"
#include "../utils/utils.h"
#include "../core/highlight.h"
#include "../core/events.h"

IMPLEMENT_APP( Application )

/**
 * Initialisation for Application
 */
bool Application::OnInit() {	
	this_ptr = this;
	
	wxImage::AddHandler(new wxPNGHandler);
	wxFileSystem::AddHandler(new wxArchiveFSHandler);
	wxFileSystem::AddHandler(new wxMemoryFSHandler);
	
	_init_log();
	if ( false==_init_single_instance() ) {
		return false;
	}
	
	wxLogMessage(_T("Application::OnInit"));
	
	Formatter::get();
	
	p_splash_frame = new SplashFrame();
	p_splash_frame->Show();

	
	DaoTask* clean_logfile_task = TaskManager::get().new_task(_clean_logfile_taskfunc, NULL);
	clean_logfile_task->Create();
	clean_logfile_task->Run();
	
	DaoTask* after_mainloop_task = TaskManager::get().new_task(_after_enter_mainloop_taskfunc, NULL);
	after_mainloop_task->Create();
	after_mainloop_task->Run();
	
    return true;
}

bool Application::_init_single_instance() {
	const wxString name = wxString::Format(_T("MyApp-%s"), wxGetUserId().c_str());
	
    p_checker = new wxSingleInstanceChecker(_T("http://www.daodict.com/dict"));
    if ( p_checker->IsAnotherRunning() ) {
        wxLogError(_("Another program instance is already running, aborting."));
        delete p_checker;
        return false;
    }
    
    return true;
}

void Application::_init_log() {
	// Init wxLog
	wxLog::SetLogLevel(wxLOG_Warning);
	wxLog::SetRepetitionCounting();
	
	wxFileName log_fn(ConfigManager::get().user_data_dir);
    log_fn.Mkdir(0777, wxPATH_MKDIR_FULL);
    
    wxDateTime now = wxDateTime::Now();
	log_fn.SetFullName(wxString::Format(_T("mainapp.%d-%d-%d.%d.log"), \
			now.GetYear(), now.GetMonth()+1, now.GetDay(), dao_get_timezone())
			);
	
	_p_logfile = new wxFFile(log_fn.GetFullPath(),_T("a+"));
	
	wxLogStderr* logger = new wxLogStderr(_p_logfile->fp());
	delete wxLog::SetActiveTarget(logger);
	//wxLog::SetTimestamp(_T("[%z %F %T]")); // on win32 EN and china local, its useless.
	wxLog::SetLogLevel(wxLOG_Info);
}


int Application::OnExit() {
	delete &ConfigManager::get();
	delete &DictManager::get();
	delete &ThemeManager::get();
	delete &TaskManager::get();
	delete p_checker;

	wxLogMessage(_T("Application::OnExit"));
	delete _p_logfile;
	return wxApp::OnExit();
}


void* Application::_clean_logfile_taskfunc(void* data) {
    wxArrayString logfiles_array;
    wxDir::GetAllFiles(ConfigManager::get().user_data_dir.GetPath(),&logfiles_array,_T("*.log"));
    
    for (int i=0;i<logfiles_array.Count();i++) {
    	wxString logfile = wxFileName(logfiles_array[i]).GetName();
    	logfile.Replace(_T("mainapp."),_T(""));
    	logfile.Replace(wxString::Format(_T(".%d"), dao_get_timezone()),_T(""));
    	
    	wxDateTime logdate;
    	logdate.ParseDate(logfile.c_str());
    	
    	wxTimeSpan interval = wxDateTime::Now().Subtract(logdate);
    	
    	if (interval.GetDays()>6) {
    		::wxLogMessage(wxString::Format(_("Delete log file: %s"), logfiles_array[i].c_str()));
    		::wxRemoveFile(logfiles_array[i]);
    	}
    }
    
    //wxMessageBox(_T("dska"));
}

void* Application::_after_enter_mainloop_taskfunc(void* data) {	
	while ( not this_ptr->IsMainLoopRunning() ) {
		wxThread::Sleep(100);
	}
	
	MainFrame* p_mainframe = (MainFrame*)this_ptr->p_splash_frame->p_main_frame;
	while (p_mainframe==NULL) {
		wxThread::Sleep(100);
		p_mainframe = this_ptr->p_splash_frame->p_main_frame;
	}
	
	wxCommandEvent evt(wxEVT_DAODICT_MAINFRAME_CREATED, MainFrame::ID_MAIN_FRAME);
	wxPostEvent(p_mainframe, evt);
}

Application* Application::this_ptr = NULL;
